package com.herui.ota.service.iml;

import cn.hutool.core.bean.BeanUtil;
import com.herui.ota.cache.CacheKeys;
import com.herui.ota.dao.mysql.UserAdminMapper;
import com.herui.ota.dao.mysql.UserMapper;
import com.herui.ota.enums.ResponseEnum;
import com.herui.ota.enums.UserIdentityEnum;
import com.herui.ota.exception.ServiceException;
import com.herui.ota.pojo.vo.UserCache;
import com.herui.ota.utils.AccountLockManager;
import com.herui.ota.utils.SmsUtils;
import org.shan.base.layer.user.dao.mysql.UserAccountMapper;
import org.shan.base.layer.user.dao.mysql.UserRoleMapper;
import org.shan.base.layer.user.entity.Role;
import org.shan.base.layer.user.entity.UserAccount;
import org.shan.base.layer.user.entity.UserRole;
import org.shan.base.layer.user.pojo.dto.UserRightDto;
import org.shan.base.layer.user.pojo.vo.RoleVo;
import org.shan.base.layer.user.service.RoleService;
import org.shan.base.layer.user.service.UserRoleService;
import org.shan.base.layer.user.service.iml.UserAccountServiceIml;
import org.shan.spring.base.utils.ServletUtils;
import org.shan.spring.cache.CacheChannel;
import org.shan.spring.cache.CacheObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;

import java.util.Random;

@Service
@Primary
public class LightUserAccountServiceIml extends UserAccountServiceIml {

    @Autowired
    protected CacheChannel cacheChannel;

    @Autowired
    private UserRoleMapper userRoleMapper;
    @Autowired
    private UserRoleService userRoleService;
    @Autowired
    private RoleService roleService;

    @Autowired
    UserAdminMapper userAdminMapper;
    @Autowired
    UserMapper userMapper;

    private AccountLockManager accountLockManager = new AccountLockManager();

    public UserRightDto getUserRoleDto(String username) {
        return ((UserAccountMapper)this.baseMapper).selectUserRightDto(username, null);
    }

    public String getUsername() {
        if (Test_Flag) {
            return User_Name;
        } else {
            Object username = ServletUtils.getAttribute("username");
            return username == null || "anonymousUser".equals(username) ? null : username.toString();
        }
    }
    public UserCache getUserCache(boolean flag) {
        if (getUsername() == null) {
            return null;
        }

        CacheObject cacheObject = cacheChannel.get(CacheKeys.USER_INFO_KEY, getUsername(), false);
        UserCache allUserInfoVo = cacheObject.getObject(UserCache.class);
        if (allUserInfoVo == null || flag) {
            UserAccount userAccount = findByUsername(getUsername());
            allUserInfoVo = new UserCache();
            BeanUtil.copyProperties(userAccount, allUserInfoVo);
            Object info = null;

            RoleVo roleVo = roleService.getByUserId(userAccount.getId());

            allUserInfoVo.setRoleVo(roleVo);
            String identity = userAccount.getIdentity();
            UserIdentityEnum userIdentityEnum = UserIdentityEnum.decode(identity);
            if (userIdentityEnum == null){
                throw new ServiceException(ResponseEnum.ROLE_FAIL.getCode(), "角色不存在");
            }

            switch (userIdentityEnum) {
                case ADMIN:
                    info = userAdminMapper.selectById(userAccount.getId());
                    break;
                case USER:
                    info = userMapper.selectById(userAccount.getId());
                    break;
            }
            allUserInfoVo.setInfo(info);

            cacheChannel.set(CacheKeys.USER_INFO_KEY, getUsername(), allUserInfoVo);
        }
        return allUserInfoVo;
    }

    public void getPhoneCode(String phone) {
        String[] chars = new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
        String msgCode = "";
        Random ran = new Random();
        for (int i = 0; i < 6; i++) {
            int num = ran.nextInt(chars.length);
            msgCode += chars[num];
        }

        String templateCode = "SMS_176600466";
        SmsUtils.sendSms(templateCode, phone, msgCode);

        log.info("{} 手机生成验证码:{}", phone, msgCode);
        cacheChannel.set(CacheKeys.PHONE_CODE_KEY, phone, msgCode);
    }

    public boolean checkPhoneCode(String phone, String code) {

        code = code.trim();
        CacheObject cacheObject = cacheChannel.get(CacheKeys.PHONE_CODE_KEY, phone, false);

        Object rawValue = cacheObject.rawValue();
        if (rawValue != null && rawValue.toString().equals(code)) {
            evict(CacheKeys.PHONE_CODE_KEY, phone);
            log.info("{} 手机校验验证码成功:{}", phone, code);
            return true;
        }

        log.info("{} 手机校验验证码失败:{}", phone, code);

        return false;
    }

    public void loginFail(Integer userId){
        accountLockManager.recordFailure(userId.toString());
    }

    public boolean isLock(Integer userId){
        return accountLockManager.isLock(userId.toString());
    }

    public void unLock(Integer userId){
        accountLockManager.unLock(userId.toString());
    }

    protected void evict(String region, String key) {
        cacheChannel.evict(region, key);
        log.debug("删除 {} {} 的缓存数据", region, key);
    }
}
